﻿0x550	341600AC	S6 = 0xAC

emus: 801468D8	SH -> NOP

800A9750	pointers to the hardware regions

Another annoying jamma game.

800260E4()	read jamma regs to 80055380
80026130(player)	V0 = player A0's controller input
	00FF0000	P1 controls
	00000001	P1 start
	FF000000	P2 controls
	00000002	P2 start
80026190()	True if service pressed
800261A0(reg)	80055380[A0]
800261B8()


800267DC()	0x1BDC	set hardware offsets to 800A9750
80026848()

8002C5D0()	0x	???, returns controller flags; calls 8002D220(), 8002D670(), 8002C610(), 8002C880()
8002C610()	0x	call 8002D550(80050440)
8002C630()	0x	call 8002D5F0(80050440)
8002C650()

8002C880()
8002C8E0()	0x	call 8002D5F0(80050470)
8002C900()
8002CAEC()
8002CC6C()
8002CCB4()

8002D220()	0x	???, returns controller flags; gets controller status
8002D2B8()

8002D670()	0x	???; determines #connected controllers, returns flags
8002D73C()	0x	call 8002D5F0(800504D8)
8002D75C()	0x	call 8003C7D0(8012AA50, 0, 1)
8002D784()	0x	call 8003C6A0(8012AA50, 0, 1)
8002D7AC()	0X	???; reads all controller states
	v = call 8003AF00(8012AA08):
	if not v:
		call 8003C6A0(8012AA08, 0, 1)
		call 8003AF80(800A6730)
	return v
8002D7FC(A0)	0x	???; gets controller state
8002D8D4()	0x	???; gets controller state
8002D94C(A0)	0x	???; gets controller state
8002DA10()	0x	???; disables reading controller input
	v = call 800366B0(1)
	800A6728 = 1
	return call 800366B0(v)
8002DA40()	0x	???; enables reading controller input
	v = call 800366B0(1)
	800A6728 = 0
	return call 800366B0(v)
8002DA70()	0x	call 8002D2B8(0x103, 0)
8002DA90()

80035B60(A0)	0x	True if 4K eeprom present and ready
80035BE0()

8003AF80(A0)	0x	call 8003B31C(SP+10, A0)
8003AFA0()	0x	get controller state
	call 8003D774()
	if @8012979C != 1:
		call 8003B0C4()	#set PIF read req
		call 8003D670(1, 800A6670)	#write from A1 to PIF
		call 8003C6A0(A0, 0, 1)
	result = call 8003D670(0, 800A6670)	#read from PIF to A1
	8012979C = 1
	call 8003D7E0()
	return result
8003B028(A0)	0x16428	copy controller data from 800A6670 to A0
8003B0C4()	0x164C4	set PIF read req to 800A6670
8003B180()	0x16580	???; fetches PIF status for P1-P4
8003B31C()	0x1671C	read PIF status result from 800A6670
8003B3D0()	0x167D0	set PIF status req to 800A6670
8003B490()	0x16890

8003C530(target, buffer, flag)
	target[0] = 800516D0
	target[1] = 800516D0
	target[2] = 0
	target[3] = 0
	target[4] = flag
	target[5] = buffer
8003C560()

8003D670(mode, source)	read or write (A0) between PIF and rdram A1
	accepts: A0=mode (0:read, 1:write), A1=p->PIF buffer
8003D720()
8003D774()
8003D7E0()
8003D810()

8003F3E4()	0x1A7E4	set PIF write ctrl slot req to 80066370
8003F630()	0x1AA30

80041F30()	0x1D330	test status and read eeprom state (buffer @ 800A6A50)
800420D8()	0x1D4D8	set PIF read eeprom req to 800A6A50
80042160()	0x1D560	read values from 800A6A50
80042314()	0x1D714	set PIF write eeprom req to 800A6A50
800423BC()	0x1D7BC	set PIF status req for eeprom (channel 5) to 800A6A50 (returns status?)
80042560()	0x1D960

8004481C()	0x1FC1C	set PIF status req to 80129D90
800448C0()	0x1FCC0	read PIF buffer at 80129D90
80044980()	0x1FD80

800504C0	p->function executed by 8002D7FC when controllers present
800504C4	p->8002D7FC()
800504C8	p->8002D8D4()
800504CC	p->8002D94C()
800504D0	p->8002D7AC()



80055380	DIP settings from hardware
	0200	read DIP switch 2	(800C9A20 = 1)
	0100	read DIP switch 1
80055382	hardware ctrl
	2000	P2 button 2
	1000	P2 button 1
	0800	P2 right
	0400	P2 left
	0200	P2 down
	0100	P2 up
	0020	P1 button 2
	0010	P1 button 1
	0008	P1 right
	0004	P1 left
	0002	P1 down
	0001	P1 up
80055384	hardware switches
	0020	test button
	0010	service button
	0008	coin slot 2
	0004	coin slot 1
	0002	P2 start
	0001	P1 start
80055386	hardware unused?
80055388

800588A8()	0x33CA8
80058B70()	0x33F70
80058DD8()	0x341D8

8006B774()	0x46B74
8006BBF0()	0x46FF0

8006C2FC()	0x476FC
8006CAD0()	0x47ED0

8006CDF4()	0x481F4
8006D210()	0x48610
8006D6EC()	0x48AEC

800A6728	If True, ignores controller input.  SET TO 0 TO READ CONTROLLERS!
800A672C

800A6998	controller input; 6 bytes each
800A69B0[0]	#controllers to read (4)
800A69B4

800A8A48	controller slot status; 3 bytes each, 1 byte padding
800A8A58	bitflags for connected controllers
800A8A59

800A8B30	#connected controllers

80351E58(A0)	???; reads ctrl
	accepts: A0=p->???
	A2 = @A0+50	#current ctrl
	T0 = @A0+54	#prev ctrl(?)
	a1, t1, t2, t3, t4 = 0, 0, 0, 0, 0
	if A2 & 0x1000:	#up
		# 80351E94
		if @A0+24 == 1:
			@A0+20 += 1
		else:
			@A0+20 = 0
		# 80341EB4
		@A0+24 += 1
		a = @A0+20
		a1 = True
		if a >= 0xF:
			t = 2//3 * a
			t>>=2
			t *= 6
		if a == t:
			t1 = 1
	if A2 & 0x4000:	#down
		# 80351E94
		if @A0+24 == 2:
			@A0+20 += 1
		else:
			@A0+20 = 0
		# 80341EB4
		@A0+24 += 1
		a = @A0+20
		a1 = True
		if a >= 0xF:
			t = 2//3 * a
			t>>=2
			t *= 6
		if a == t:
			t2 = 1
	if A2 & 0x2000:	#right
		# 80351E94
		if @A0+24 == 3:
			@A0+20 += 1
		else:
			@A0+20 = 0
		# 80341EB4
		@A0+24 += 1
		a = @A0+20
		a1 = True
		if a >= 0xF:
			t = 2//3 * a
			t>>=2
			t *= 6
		if a == t:
			t3 = 1
	if A2 & 0x8000:	#left
		# 80351E94
		if @A0+24 == 4:
			@A0+20 += 1
		else:
			@A0+20 = 0
		# 80341EB4
		@A0+24 += 1
		a = @A0+20
		a1 = True
		if a >= 0xF:
			t = 2//3 * a
			t>>=2
			t *= 6
		if a == t:
			t4 = 1
	# 80352020
	if not a1:
		@A0+24 = 0
		@A0+20 = 0
	if (T0 & 0x1000) and t1:
		a3 = True
		s0 -= 2
		if s0 <= 0: s0 = 8
		if 8009C368[@A0+40 ^ 1] == s0:
			s0 -= 2
	if (T0 & 0x4000) and t2:
		a3 = True
		s0 += 2
		if s0 > 8: s0 -= 8
		if 8009C368[@A0+40 ^ 1] == s0:
			s0 += 2
	if (T0 & 0x2000) and t3:
		etc...
	if (T0 & 0x8000) and t4:
		etc...
	# 8035216C
	if a3:
		call 8013E3DC(0x1E, 2, 2, 0)
		@A0+1C = s0
		8009C368[@A0+40] = s0
		call 803519D8(A0)
	@A0+30 += @A0+34
	...
80352230()

8037C048()	0xD1C58	controls, maybe only on debug menu
	call 800260E4()
	for i in range(2):
		ctrl = call 80026130(i)
		regs = 0x1000 if ctrl & 0x001 else 0	#up
		regs|= 0x4000 if ctrl & 0x002 else 0	#down
		regs|= 0x8000 if ctrl & 0x004 else 0	#left
		regs|= 0x2000 if ctrl & 0x008 else 0	#right
		regs|= 0x0020 if ctrl & 0x010 else 0	#button 1
		regs|= 0x0040 if ctrl & 0x020 else 0	#button 2
		regs|= 0x0010 if ctrl & 0x040 else 0	#button 3
		regs|= 0x0800 if ctrl & 0x100 else 0	#start
		target = @80389B40 + (i * 0x20)
		target[20:24] = target[8:12]
		target[8:12] = regs

8037C168()	0xD1D78


ORDER OF OPERATIONS:
800260E4 sets 80055380[0:8:2] to hardware
mulitple functions read them
@8002D898, JAL @800504C0(A0) to process controller input


@8037C02C	0xD1C3C	change JAL from 8002DA10 to 8002DA40 to enable controllers

800267DC(target)	0x1BDC	slightly ammended address ranges
LUI	V1,8000
LUI	V0,0040
SW	V1,0000 (A0)
SW	V0,0004 (A0)
LUI	V1,8040
ADDIU	V0,R0,4000
SW	V1,0010 (A0)
SW	V0,0014 (A0)
LUI	V1,B000
ADDIU	V0,R0,0400
ADDIU	V1,V1,0C00
SW	V0,000C (A0)
JR	RA
SW	V1,0008 (A0)
3C0380003C020040AC830000AC8200043C03804024024000AC830010AC8200143C03B0002402040024630C00AC82000C03E00008AC830008

LUI	V0,8004
ADDIU	V0,V0,B080
LUI	V1,8005
SW	V0,04C0 (V1)

Write a function to map controller input into the DIP registers at 800A9758.

	accepts: A0=p->some fool stupid thing I don't need to mess with
OR	AT,R0,R0
OR	A1,R0,R0
OR	A2,R0,R0
LUI	A3,800A
@ loopus
LHU	A0,6998 (A3)
SRL	A1,A1,0x8
ANDI	V0,A0,003C
ANDI	V1,A0,1000
OR	A2,A2,V0
SLLV	V1,V1,AT
ANDI	V0,A0,8800
SRL	V1,V1,0xC
SRL	V0,V0,0x3
OR	A2,A2,V1
OR	A1,A1,V0
ANDI	V1,A0,4400
ANDI	V0,A0,0200
SRL	V1,V1,0x1
SLL	V0,V0,0x1
OR	A1,A1,V1
ANDI	V1,A0,0100
OR	A1,A1,V0
SLL	V1,V1,0x3
ADDIU	A3,A3,0006
OR	A1,A1,V1
BEQ	AT,R0,loopus
ADDIU	AT,AT,0001
@ set
LUI	A0,800B
NOR	A1,R0,A1
LW	A0,9758 (A0)
NOR	A2,R0,A2
SH	A1,0002 (A0)
JR	RA
SH	A2,0004 (A0)

8003B080()	0x16480
3C07800A 00000825 00002825 00003025 94E46998 00052A02 3082003C 30831000 00C23025 00231804 30828800 00031B02 000210C2 00C33025 00A22825 30834400 30820200 00031842 00021040 00A32825 30830100 00A22825 000318C0 24E70006 00A32825 1020FFEA 24210001 3C04800B 00052827 8C849758 00063027 A4850002 03E00008 A4860004

Optional: 64Drive writable cartrom space for full hardware implementation
We'll hack the bootstrap a bit to make this happen.  Nothing else has PI access...

~80000250	0x710
AD170014	SW	S7,0014 (T0)
3C09B000	LUI	T1,B000
AD090008	SW	T1,0008 (T0)
@ 64drive
3C080020	LUI	T0,0020
3C09B800	LUI	T1,B800
240A00F0	ADDIU	T2,R0,00F0
@ loopus
8D2B0200	LW	T3,0200 (T1)
000B5A03	SRL	T3,T3,0x8
51600003	BEQL	T3,R0,+3
AD2A0208	SW	T2,0208 (T1)
1500FFFB	BNE	T0,R0,loopus
2508FFFF	ADDIU	T0,T0,FFFF
@ end_64drive
3C08A400	LUI	T0,A400
21091000	ADDI	T1,T0,1000
240AFFFF	ADDIU	T2,R0,FFFF
25080004	ADDIU	T0,T0,0004
1509FFFE	BNE	T0,T1,80000280
AD0AFFFC	SW	T2,FFFC (T0)
21091000	ADDI	T1,T0,1000
25080004	ADDIU	T0,T0,0004
1509FFFE	BNE	T0,T1,80000298
AD0AFFFC	SW	T2,FFFC (T0)
3C0AA400	LUI	T2,A400
240B13ED	ADDIU	T3,R0,13ED
AD4B1000	SW	T3,1000 (T2)
3C0BB000	LUI	T3,B000
254A1000	ADDIU	T2,T2,1000
8D690008	LW	T1,0008 (T3)
3C010010	LUI	AT,0010
01214823	SUBU	T1,T1,AT
01200008	JR	T1
00000000	NOP

This works, but the writes to ROM don't occur properly w/o looping PI Status, etc.  Probably not worth the effort.
